<template>
  <div class="chat-container">
    <!-- 左侧联系人列表 -->
    <div class="contact-list">
      <ContactList
        :activeTab="activeTab"
        :myContacts="myContacts"
        :colleagueContacts="colleagueContacts"
        :currentContact="currentContact"
        @selectContact="selectContact"
        @update:activeTab="handleTabChange"
      />
    </div>
    <!-- 右侧聊天区 -->
    <div class="chat-main">
      <!-- 顶部标题栏 -->
      <ChatHeader
        :currentContact="currentContact"
        :isColleagueChat="isColleagueChat"
        @transfer="transferSession"
        @update:customerName="handleCustomerNameUpdate"
      />
      <!-- 消息列表 -->
      <MessageList
        ref="messageListRef"
        :messages="messages"
        :sessionId="currentContact?.id"
        :currentContact="currentContact"
        @update:messages="updateMessages"
      />
      <!-- 工具栏+输入框 -->
      <ChatInput
        v-if="!isColleagueChat"
        :input="input"
        @update:input="(val) => (input = val)"
        @sendMessage="sendMessage"
        @sendFile="sendFile"
      />
      <div v-else class="colleague-chat-notice">
        <el-alert
          title="您正在查看同事的会话，无法发送消息"
          type="info"
          :closable="false"
          show-icon
        />
      </div>
    </div>
  </div>
</template>

<script setup>
defineOptions({
  name: "Chat",
});

import { ref, onMounted, onBeforeUnmount, computed } from "vue";
import ContactList from "./components/ContactList.vue";
import ChatHeader from "./components/ChatHeader.vue";
import MessageList from "./components/MessageList.vue";
import ChatInput from "./components/ChatInput.vue";
import { useUserStoreHook } from "@/store/modules/user.store";
import { useStomp } from "@/hooks/useStomp";
import ChatAPI from "@/api/chat.api";
import FileAPI from "@/api/file.api";
import { ElMessage } from "element-plus";
import { formatDateTime } from "@/utils/date";
import SoundService from "@/utils/notification";

const userStore = useUserStoreHook();
const token = localStorage.getItem("token");
const socketEndpoint = ref(import.meta.env.VITE_APP_WS_ENDPOINT);
const { connect, subscribe, disconnect, send, setOnConnect } = useStomp({
  brokerURL: socketEndpoint.value,
  debug: true,
  token,
});

const activeTab = ref("mine");
const myContacts = ref([]); // 会话列表
const colleagueContacts = ref([]); // 可选：同事会话
const currentContact = ref(null); // 当前选中的会话
const sessionMap = ref({}); // { sessionId: [msg, ...] } - 唯一的消息数据源
const messageListRef = ref(null); // 消息列表组件引用
const input = ref("");

// 当前会话的消息列表 - 从sessionMap中获取，不再单独维护
const messages = computed(() => {
  if (!currentContact.value) return [];
  return sessionMap.value[currentContact.value.id] || [];
});

// 判断当前是否为同事会话
const isColleagueChat = computed(() => {
  if (!currentContact.value) return false;
  // 检查当前会话是否在同事会话列表中
  return (
    activeTab.value === "colleague" ||
    colleagueContacts.value.some((contact) => contact.id === currentContact.value.id)
  );
});

// 获取会话列表
async function fetchSessions() {
  try {
    const res = await ChatAPI.getSessions();
    const sessions = res.list || [];

    // 构建旧联系人 Map，便于合并字段
    const oldMyContactsMap = new Map(myContacts.value.map((c) => [c.id, c]));
    const oldColleagueContactsMap = new Map(colleagueContacts.value.map((c) => [c.id, c]));

    myContacts.value = [];
    colleagueContacts.value = [];

    sessions.forEach((session) => {
      // 先找旧联系人
      const oldContact =
        session.agentId === userStore.userInfo.userId
          ? oldMyContactsMap.get(session.id)
          : oldColleagueContactsMap.get(session.id);
      const contact = {
        id: session.id,
        name: session.customerName,
        agentAvatar: session.agentAvatar,
        avatar: session.customerAvatar || "",
        lastMsg: session.lastMsg !== undefined ? session.lastMsg : oldContact?.lastMsg || "",
        unread: session.unreadCount !== undefined ? session.unreadCount : oldContact?.unread || 0,
        customerId: session.customerId,
        sendTime:
          session.lastMsgTime !== undefined ? session.lastMsgTime : oldContact?.sendTime || "",
      };
      if (session.agentId === userStore.userInfo.userId) {
        myContacts.value.push(contact);
      } else {
        colleagueContacts.value.push(contact);
      }
    });
  } catch (error) {
    console.error("获取会话列表失败", error);
  }
}

// 连接成功后的回调
function onConnected(_frame) {
  console.log("WebSocket连接成功，开始订阅消息");

  // 初始化声音和通知服务
  SoundService.init();

  // 订阅客户消息 - 个人消息
  subscribe(`/user/${userStore.userInfo.userId}/queue/customer-message`, onCustomerMessage);

  // 订阅未分配客服的客户消息 - 广播消息
  subscribe("/topic/customer-to-agent", onUnassignedCustomerMessage);

  // 订阅新客户通知
  subscribe(`/user/${userStore.userInfo.userId}/queue/new-customer`, onNewCustomer);

  // 订阅未分配客服的客户通知
  subscribe("/topic/no-agent-customer", onNoAgentCustomer);

  // 订阅转接会话通知
  subscribe(`/user/${userStore.userInfo.userId}/queue/transferred-session`, onTransferredSession);
  // 订阅转接会话出去成功通知
  subscribe(`/user/${userStore.userInfo.userId}/queue/session-transferred`, onSessionTransferred);

  // 订阅消息已读通知
  subscribe(`/user/${userStore.userInfo.userId}/queue/message-read`, onMessageRead);

  // 获取会话列表
  fetchSessions();
}

function onCustomerMessage(msg) {
  const message = JSON.parse(msg.body);
  handleIncomingMessage(message);

  // 如果窗口没有焦点或者当前不在这个会话，播放声音并显示通知
  if (
    !document.hasFocus() ||
    !currentContact.value ||
    currentContact.value.id !== message.sessionId
  ) {
    // 显示新消息通知
    SoundService.showNewMessageNotification(message.senderName, message.content, () => {
      // 点击通知时，如果已经有会话则选中它
      const session = myContacts.value.find((s) => s.id === message.sessionId);
      if (session) {
        selectContact(session);
      }
    });
  }
}

function onUnassignedCustomerMessage(msg) {
  const message = JSON.parse(msg.body);
  handleIncomingMessage(message);
}

function onNewCustomer(msg) {
  const message = JSON.parse(msg.body);
  // 处理新客户通知
  console.log("新客户接入:", message);

  // 显示新客户通知
  if (message.customerName) {
    SoundService.showNewCustomerNotification(message.customerName, () => {
      // 点击通知时刷新会话列表并尝试找到新会话
      fetchSessions().then(() => {
        // 尝试找到对应的会话
        if (message.sessionId) {
          const session = myContacts.value.find((s) => s.id === message.sessionId);
          if (session) {
            selectContact(session);
          }
        }
      });
    });
  }

  // 刷新会话列表
  fetchSessions();
}

function onNoAgentCustomer(msg) {
  const message = JSON.parse(msg.body);
  // 处理未分配客服的客户通知
  console.log("未分配客服的客户:", message);

  // 显示未分配客服的客户通知
  if (message.customerName) {
    SoundService.showNewCustomerNotification(message.customerName, () => fetchSessions());
  }

  // 刷新会话列表
  fetchSessions();
}

function onTransferredSession(msg) {
  const message = JSON.parse(msg.body);
  // 处理转接会话通知
  console.log("收到转接会话:", message);

  // 添加系统消息到会话中
  if (message.sessionId) {
    // 确保会话映射中有此会话
    if (!sessionMap.value[message.sessionId]) {
      sessionMap.value[message.sessionId] = [];
    }

    // 添加系统消息
    const systemMessage = {
      id: Date.now() + Math.random().toString(36).substring(2, 8), // 确保ID唯一
      fromMe: false,
      avatar: "",
      type: "text",
      content: `${message.senderName || "系统"} 将会话转接给了您，请及时回复客户`,
      senderType: "system",
      senderName: "系统通知",
      sendTime: formatDateTime(new Date()),
    };

    sessionMap.value[message.sessionId].push(systemMessage);

    // 如果当前正在查看此会话，更新消息列表
    if (
      currentContact.value &&
      currentContact.value.id === message.sessionId &&
      messageListRef.value
    ) {
      messageListRef.value.scrollToBottom();
    }

    // 显示通知
    ElMessage({
      type: "success",
      message: `收到转接会话，来自 ${message.senderName || "系统"}`,
    });
  }

  // 刷新会话列表
  fetchSessions();
}

function onSessionTransferred(msg) {
  const message = JSON.parse(msg.body);
  // 处理转接会话成功通知
  console.log("会话转接成功:", message);
  // 如果有会话ID，从会话列表中移除
  if (message.sessionId) {
    const index = myContacts.value.findIndex((contact) => contact.id === message.sessionId);
    if (index !== -1) {
      // 如果是当前会话，清空当前会话
      if (currentContact.value && currentContact.value.id === message.sessionId) {
        currentContact.value = null;
        messages.value = [];
      }

      // 从会话列表中移除
      myContacts.value.splice(index, 1);

      // 显示提示消息
      ElMessage({
        type: "success",
        message: `会话已成功转接给 ${message.targetName || "其他客服"}`,
      });
    }
  }

  // 刷新会话列表
  fetchSessions();
}

function onMessageRead(msg) {
  const data = JSON.parse(msg.body);
  const { sessionId } = data;

  // 更新消息的已读状态
  if (sessionMap.value[sessionId]) {
    sessionMap.value[sessionId].forEach((msg) => {
      msg.hasRead = 1;
    });
  }
}

function handleIncomingMessage(message) {
  // 维护会话列表
  let session = myContacts.value.find((s) => s.id === message.sessionId);
  if (!session) {
    // 新会话，添加到会话列表
    session = {
      id: message.sessionId,
      name: message.senderName,
      avatar: message.senderAvatar || "",
      lastMsg: message.content,
      unread: 1,
      customerId: message.senderId,
      sendTime: formatDateTime(new Date()),
    };
    myContacts.value.unshift(session);
  } else {
    // 已有会话，更新最后消息和未读数
    session.lastMsg = message.content;
    session.unread = (session.unread || 0) + 1;
    session.sendTime = formatDateTime(new Date());
  }

  // 创建新消息对象
  const newMessage = {
    id: message.id || Date.now() + Math.random().toString(36).substring(2, 8), // 确保ID唯一
    fromMe: false,
    avatar: session.avatar,
    type: message.type || "text",
    content: message.content,
    senderType: message.senderType || "customer",
    senderName: message.senderName || session.name,
    fileUrl: message.fileUrl,
    fileName: message.fileName,
    fileSize: message.fileSize,
    sendTime: message.createTime || formatDateTime(new Date()),
    hasRead: 0, // 添加初始状态
  };

  // 维护消息列表
  if (!sessionMap.value[message.sessionId]) sessionMap.value[message.sessionId] = [];

  // 添加消息到会话映射
  sessionMap.value[message.sessionId].push(newMessage);

  // 如果当前会话就是这个，通知消息列表组件更新
  if (
    currentContact.value &&
    currentContact.value.id === message.sessionId &&
    messageListRef.value
  ) {
    // 直接调用scrollToBottom，不再调用addMessage
    messageListRef.value.scrollToBottom();
    session.unread = 0;
  }

  // 如果不是当前会话的消息，但窗口有焦点，只播放声音不显示通知
  if (
    document.hasFocus() &&
    (!currentContact.value || currentContact.value.id !== message.sessionId)
  ) {
    SoundService.playNewMessageSound();
  }
  // 如果是当前会话的消息，发送已读状态
  sendMessageReadStatus();
}

function selectContact(contact) {
  currentContact.value = contact;
  // 清除未读
  contact.unread = 0;
  // 如果是当前会话的消息，发送已读状态
  if (contact.id) {
    sendMessageReadStatus();
  }
}

// 更新消息列表
function updateMessages(newMessages, sessionId) {
  sessionMap.value[sessionId] = newMessages;
}

function sendMessage() {
  if (!input.value.trim() || !currentContact.value) return;
  // 如果是同事会话，不允许发送消息
  if (isColleagueChat.value) {
    ElMessage({
      type: "warning",
      message: "无法在同事会话中发送消息",
    });
    return;
  }

  const sessionId = currentContact.value.id;
  const customerId = currentContact.value.customerId;
  const currentTime = formatDateTime(new Date());
  const messageId = Date.now() + Math.random().toString(36).substring(2, 8); // 生成唯一ID

  send(
    "/app/agent/send",
    {},
    JSON.stringify({
      senderId: userStore.userInfo.userId,
      senderName: userStore.userInfo.nickname,
      senderType: "agent",
      sessionId,
      content: input.value,
      targetId: customerId,
      type: "text",
      createTime: currentTime,
      id: messageId, // 发送唯一ID
    })
  );

  // 本地添加消息
  if (!sessionMap.value[sessionId]) sessionMap.value[sessionId] = [];

  const message = {
    id: messageId, // 使用相同的ID
    fromMe: true,
    avatar: "",
    type: "text",
    content: input.value,
    senderType: "agent",
    senderName: userStore.userInfo.nickname,
    sendTime: currentTime,
    hasRead: 0, // 添加初始状态
  };

  // 添加到会话映射
  sessionMap.value[sessionId].push(message);

  // 更新会话列表的最后消息
  currentContact.value.lastMsg = input.value;
  currentContact.value.sendTime = currentTime;

  // 通知消息列表组件滚动到底部
  if (messageListRef.value) {
    messageListRef.value.scrollToBottom();
  }

  input.value = "";
}

// 发送文件
async function sendFile(file) {
  if (!currentContact.value) return;
  // 如果是同事会话，不允许发送文件
  if (isColleagueChat.value) {
    ElMessage({
      type: "warning",
      message: "无法在同事会话中发送文件",
    });
    return;
  }

  const sessionId = currentContact.value.id;
  const customerId = currentContact.value.customerId;
  const currentTime = formatDateTime(new Date());
  const messageId = Date.now() + Math.random().toString(36).substring(2, 8); // 生成唯一ID

  try {
    // 使用FileAPI.upload方法上传文件
    const formData = new FormData();
    formData.append("file", file);
    // 可以添加额外参数
    formData.append("sessionId", sessionId);
    formData.append("customerId", customerId);

    // 上传文件
    const response = await FileAPI.upload(formData);
    // 发送文件消息
    send(
      "/app/agent/send",
      {},
      JSON.stringify({
        senderId: userStore.userInfo.userId,
        senderName: userStore.userInfo.nickname,
        senderType: "agent",
        sessionId,
        content: response.url,
        targetId: customerId,
        type: "file",
        createTime: currentTime,
        id: messageId, // 发送唯一ID
      })
    );

    // 本地添加消息
    if (!sessionMap.value[sessionId]) sessionMap.value[sessionId] = [];

    const message = {
      id: messageId, // 使用相同的ID
      fromMe: true,
      avatar: "",
      type: "file",
      content: response.url,
      senderType: "agent",
      senderName: userStore.userInfo.nickname,
      sendTime: currentTime,
    };

    // 添加到会话映射
    sessionMap.value[sessionId].push(message);

    // 更新会话列表的最后消息
    currentContact.value.lastMsg = `[文件] ${file.name}`;
    currentContact.value.sendTime = currentTime;

    // 通知消息列表组件滚动到底部
    if (messageListRef.value) {
      messageListRef.value.scrollToBottom();
    }

    // 显示上传成功消息
    ElMessage.success("文件上传成功");
  } catch (error) {
    console.error("文件上传失败", error);
    ElMessage.error("文件上传失败");
  }
}

// 会话转接功能
function transferSession(targetAgentId) {
  if (!currentContact.value) return;
  // 如果是同事会话，不允许转接
  if (isColleagueChat.value) {
    ElMessage({
      type: "warning",
      message: "无法转接同事会话",
    });
    return;
  }

  const sessionId = currentContact.value.id;

  // 显示加载提示
  const loadingMessage = ElMessage({
    type: "info",
    message: "正在转接会话...",
    duration: 0,
  });

  // 发送转接请求
  send(
    "/app/session/transfer",
    {},
    JSON.stringify({
      senderId: userStore.userInfo.userId,
      senderName: userStore.userInfo.nickname,
      sessionId,
      targetId: targetAgentId,
    })
  );

  // 添加系统消息到当前会话
  if (!sessionMap.value[sessionId]) sessionMap.value[sessionId] = [];

  const message = {
    id: Date.now() + Math.random().toString(36).substring(2, 8), // 确保ID唯一
    fromMe: false,
    avatar: "",
    type: "text",
    content: "正在将会话转接给其他客服...",
    senderType: "system",
    senderName: "系统通知",
    sendTime: formatDateTime(new Date()),
  };

  // 添加消息到会话映射
  sessionMap.value[sessionId].push(message);

  // 通知消息列表组件滚动到底部
  if (messageListRef.value) {
    messageListRef.value.scrollToBottom();
  }

  // 3秒后关闭加载提示
  setTimeout(() => {
    loadingMessage.close();
  }, 3000);
}

// 处理标签切换
function handleTabChange(val) {
  activeTab.value = val;
  fetchSessions();
}

// 处理客户名称更新
async function handleCustomerNameUpdate({ sessionId, customerName }) {
  if (!sessionId || !customerName) return;

  // 更新当前选中的联系人名称
  if (currentContact.value && currentContact.value.id === sessionId) {
    currentContact.value.name = customerName;
  }

  // 更新联系人列表中的名称
  const myContact = myContacts.value.find((contact) => contact.id === sessionId);
  if (myContact) {
    myContact.name = customerName;
  }

  const colleagueContact = colleagueContacts.value.find((contact) => contact.id === sessionId);
  if (colleagueContact) {
    colleagueContact.name = customerName;
  }

  // 也可以选择直接刷新会话列表
  // await fetchSessions();
}

// 发送消息已读状态
function sendMessageReadStatus() {
  const sessionId = currentContact.value.id;
  if (!sessionId) return;
  if (document.hidden) return;

  send(
    "/app/agent/read",
    {},
    JSON.stringify({
      sessionId,
    })
  );
}
// 监听页面可见性变化
onMounted(() => {
  document.addEventListener("visibilitychange", () => {
    // 当页面变为可见时，标记消息已读
    if (!document.hidden) {
      sendMessageReadStatus();
    }
  });
});

onUnmounted(() => {
  document.removeEventListener("visibilitychange", () => {
    if (!document.hidden) {
      sendMessageReadStatus();
    }
  });
});

onMounted(() => {
  // 设置连接成功回调
  setOnConnect(onConnected);

  // 连接WebSocket
  connect();
});
onBeforeUnmount(() => {
  disconnect();
});
</script>

<style scoped>
.chat-container {
  display: flex;
  height: 100%;
}
.contact-list {
  width: 260px;
  border-right: 1px solid #eee;
  background: #fafbfc;
  height: 100%;
}
.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.colleague-chat-notice {
  padding: 20px;
  background: #fff;
  border-top: 1px solid #eee;
}
</style>
